/**
 * <p>Original Author:  jessefreeman</p>
 * <p>Class File: PropertyMap.as</p>
 *
 * <p>Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:</p>
 *
 * <p>The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.</p>
 *
 * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.</p>
 *
 * <p>Licensed under The MIT License</p>
 * <p>Redistributions of files must retain the above copyright notice.</p>
 *
 * <p>Revisions<br/>
 * 	2.0  Initial version April 9, 2009</p>
 *
 */

package camo.core.property
{
    import flash.net.registerClassAlias;
    import flash.utils.ByteArray;
    import flash.utils.Dictionary;

    dynamic public class PropertyMap extends AbstractSelector
    {
        protected var propsByType:Dictionary = new Dictionary(true);
        public var propertyTypes:Array = new Array();

        /**
         *
         *
         */
        public function PropertyMap()
        {
            super(this);
        }

        /**
         *
         *
         */
        override protected function registerClass():void
        {
            registerClassAlias("camo.core.property.PropertyMap", PropertyMap);
        }

        /**
         *
         * @param name
         * @param value
         *
         */
        override protected function $setProperty(name:*, type:*):void
        {
            type = type.toLowerCase();

            super.$setProperty(name, type);

            registerType(name, type);
        }

        /**
         *
         * @param name
         * @param type
         *
         */
        protected function registerType(name:String, type:String):void
        {

            if (!propsByType[type])
                propsByType[type] = new Array();

            propsByType[type].push(name);

            if (propertyTypes.indexOf(type) == -1)
                propertyTypes.push(type);
        }

        /**
         *
         * @param type
         * @return
         *
         */
        public function getPropsByTypes(... types):Array
        {

            var results:Array = new Array();

            var key:String;

            for (key in propsByType)
            {

                if ((types.indexOf(key) != -1) && (propsByType[key]))
                {
                    var props:Array = propsByType[key].slice();
                    results = results.concat(props);
                }
            }

            return results;
        }

        /**
         *
         * @param name
         * @return
         *
         */
        override protected function $deleteProperty(name:*):Boolean
        {
            var type:String = properties[name];
            var wasDeleted:Boolean = super.$deleteProperty(name);

            if (wasDeleted)
            {
                propsByType[type].splice(propsByType[type].indexOf(name.toString()), 1);
            }

            return wasDeleted;
        }

        /**
         *
         * @return
         *
         */
        override public function clone():ISelector
        {
            var myBA:ByteArray = new ByteArray();
            myBA.writeObject(this);
            myBA.position = 0;
            return (PropertyMap(myBA.readObject()));
        }
    }
}